using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;


namespace Pokemon
{
    /// <summary>
    /// This is a game component that implements IUpdateable.
    /// </summary>
    public class Sprite
    {
        private Texture2D _texture;

        private Vector2 _size;

        private Vector2 _centerPoint;

        private int _frameIndex;

        private int _nFrame;

        private int _numFrameOfRow;

        private int _numFrameOfCol;

        /// <summary>
        /// 
        /// </summary>
        /// <param name="game">Indicate Game Instance</param>
        /// <param name="texture2">Indicate Bitmap that sprite hold</param>
        /// <param name="nFrame">Indicate number of frame</param>
        /// <param name="size">Indicate size of a frame</param>
        /// <param name="centerPoint">Indicate centerPoint</param>
        /// <param name="flag">Indicate how to get next rectangle frame, if flag == false, get RectWidth, else get RectHeight</param>
        public Sprite(Texture2D texture2, int nFrame, Vector2 size, Vector2 centerPoint, bool flag)
        {
            _texture = texture2;

            _size = size;

            _centerPoint = centerPoint;

            _frameIndex = 0;

            _nFrame = nFrame;

            _numFrameOfRow = _nFrame/(int)(Texture.Height/_size.Y);

            _numFrameOfCol = _nFrame/(int)(Texture.Width/_size.X);

            if (flag == false)
                GetNextRect += GetNextRectFromTextureWidth;
            else
                GetNextRect += GetNextRectFromTextureHeight;
        }

        public void Reset()
        {
            _frameIndex = 0;
        }

        public Vector2 Size
        {
            get { return _size; }
            set { _size = value; }
        }

        public int NFrame
        {
            get { return _nFrame; }
            set { _nFrame = value; }
        }

        public int FrameIndex
        {
            get { return _frameIndex; }
            set { _frameIndex = value; }
        }

        public Vector2 CenterPoint
        {
            get { return _centerPoint; }
            set { _centerPoint = value; }
        }

        public Texture2D Texture
        {
            get { return _texture; }
        }

        /// <summary>
        /// Allows the game component to update itself.
        /// </summary>
        /// <param name="gameTime">Provides a snapshot of timing values.</param>
        public void Update()
        {
            _frameIndex = (_frameIndex + 1)% _nFrame;
        }

        public delegate Rectangle FuncGetNextRect();

        public FuncGetNextRect GetNextRect;

        public Rectangle GetNextRectFromTextureWidth()
        {
            return new Rectangle((_frameIndex % _numFrameOfRow) * (int)_size.X, 
                (_frameIndex / _numFrameOfRow) * (int)_size.Y, 
                (int)_size.X, (int)_size.Y);
        }

        public Rectangle GetNextRectFromTextureHeight()
        {
            return new Rectangle((_frameIndex / _numFrameOfCol) * (int)_size.X, 
                (_frameIndex % _numFrameOfCol)* (int)_size.Y, 
                (int)_size.X, (int)_size.Y);
        }

        public void Draw(SpriteBatch sp, Vector2 position, Color color)
        {            
            sp.Draw(Texture, position, GetNextRect(), color);         
        }

        public void Draw(SpriteBatch sp, Vector2 position, Rectangle rect, Color color, float rotation, Vector2 origin, float scale, SpriteEffects effect, float layerDepth)
        {
            sp.Draw(Texture, position, rect, color, rotation, origin, scale, effect, layerDepth);
        }

        public void Draw(SpriteBatch sp, Vector2 position, Rectangle rect, Color color, float rotation, Vector2 origin, Vector2 scale, SpriteEffects effect, float layerDepth)
        {
            sp.Draw(Texture, position, rect, color, rotation, origin, scale, effect, layerDepth);
        }
    }
}
